/*
 * qc slave mode data control.
 * Copyright (c) 2012  everyone
 * All rights reserved.
 * no limite
 */
#include "qcom.h"
#include "mb_box_input.h"
#include "par_tab.h"
#include "par_prog.h"
#include "sys_task.h"
#include "mb_box_hold.h"

/*******************************************************************************
 * @brief  arg
 *****************************************************************************/
static uu08 prog_page_size = 128;

/*******************************************************************************
 * @brief  function
 *****************************************************************************/

/*******************************************************************************
 * @brief  reg_hold_read
 * \param[in] Index : data address
 * @return  data
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
uint16_t qc_reg_prog_get(uint16_t Index)
{
	word_tt Val = {0};

#if PROG_SEG_MAX > 0
	// 程序段 0x1000-0x1FFF

	// 2K 个通道划分为一个区。 0区掉电记忆，1区不记忆
	uu16 sub = Index & 0x7FF;
	uu16 seg = sub >> 4, offset = sub & 0x0F;

	// 程序段计算 时段0为定值，1~n为程序
	if (seg)
		seg += prog_page_size * mb_reg_remote_opt_prog_page;

	if (seg > PROG_SEG_MAX)
	{
		if (0 == offset)
			return -1;
		else
			return 0;
	}

	switch (offset)
	{
	case 0: // 时间
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(time));
		break;
	case 1: // 温度
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(temp));
		break;
	case 2: // 湿度
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(humi));
		break;
	case 3: // 转速
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(speed));
		break;
	case 4: // 紫外
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(uv));
		break;
	case 5: // 光照1
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(light));
		break;
	case 6: // 光照2
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(light2));
		break;
	case 7: // 光照3
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(light3));
		break;
	case 8: // 光照4
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(light4));
		break;
	case 9: // CO2 浓度
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(co2));
		break;
	case 10: // O2 浓度
		Val.iVal = prog_val_get(Gst.prog.group, seg, seg_par_pos(o2));
		break;
	case 11: // O3 浓度
		break;
	case 12: // 风速
		break;
	}
#endif

	return Val.uVal;
}

/*******************************************************************************
 * @brief  reg_hold_write
 * \param[in] Index : data address
 * \param[in] Val : data
 * @return  data
 * @ Pass/ Fail criteria: none
 *******************************************************************************/
void qc_reg_prog_set(uint16_t Index, uint16_t Val)
{
	u16_tt vset;

	vset.uval = Val;

// 程序段： 0x1000-0x1FFF
#if PROG_SEG_MAX > 0
	// 2K 个通道划分为一个区。 0区掉电记忆，1区不记忆
	uu16 zone = Index >> 11, sub = Index & 0x7FF;
	uu16 seg = sub >> 4, offset = sub & 0x0F;
	uu08 save_req;
	uu08 group = Gst.prog.group;

	zone &= 1;
	if (zone)
		save_req = DIS;
	else
		save_req = PRG;

	// 程序段计算 时段0为定值，1~n为程序
	if (seg)
		seg += prog_page_size * mb_reg_remote_opt_prog_page;

	if (seg > PROG_SEG_MAX)
		return;

	// 编辑段同步
	par_opt.edit.seg = seg;

	// 设定接口内部修正参数，此处无需额外处理
	switch (offset)
	{
	case 0: // 时间
		prog_val_set(group, seg, seg_par_pos(time), vset.ival, save_req);
		break;
	case 1: // 温度
		prog_val_set(group, seg, seg_par_pos(temp), vset.ival, save_req);
		break;
	case 2: // 湿度
		prog_val_set(group, seg, seg_par_pos(humi), vset.ival, save_req);
		break;
	case 3: // 转速
		prog_val_set(group, seg, seg_par_pos(speed), vset.ival, save_req);
		break;
	case 4: // 紫外
		prog_val_set(group, seg, seg_par_pos(uv), vset.uval, save_req);
		break;
	case 5: // 光照1
		prog_val_set(group, seg, seg_par_pos(light), vset.uval, save_req);
		break;
	case 6: // 光照2
		prog_val_set(group, seg, seg_par_pos(light2), vset.uval, save_req);
		break;
	case 7: // 光照3
		prog_val_set(group, seg, seg_par_pos(light3), vset.uval, save_req);
		break;
	case 8: // 光照4
		prog_val_set(group, seg, seg_par_pos(light4), vset.uval, save_req);
		break;
	case 9: // CO2
		prog_val_set(group, seg, seg_par_pos(co2), vset.ival, save_req);
		break;
	case 10: // O2
		prog_val_set(group, seg, seg_par_pos(o2), vset.ival, save_req);
		break;
	case 11: // O3
		break;
	case 12: // 风速
		break;
	}
#endif
}

#if PROG_SEG_MAX > 0
/*******************************************************************************
 * @brief  程序页面操作
 * \param[in] Val : data
 * @return  data
 * @ Pass/ Fail criteria: none
 *******************************************************************************/
void qc_reg_prog_opt(uint16_t Val)
{
	ii08 seg_max = prog_seg_max(&prog_run_obj);

	// seg_max 指示最后一个有效段索引，同时也是当前有效段数量。
	// 时段n所在页面。 Pn = (n-1)/prog_page_size
	if (seg_max < 1)
		seg_max = 1;

	// 分离页面
	prog_page_size = Val / 100;
	if (prog_page_size > 128)
		prog_page_size = 128;

	// 分离命令
	Val %= 100;

	if (Val == 33) // 首页
	{
		mb_reg_remote_opt_prog_page = 0;
	}
	else if (Val == 55) // 尾页
	{
		// 第一个无效段所在页 (seg_max+1)
		mb_reg_remote_opt_prog_page = seg_max / prog_page_size;

		// 页面范围
		if (mb_reg_remote_opt_prog_page > (PROG_SEG_MAX - 1) / prog_page_size)
			mb_reg_remote_opt_prog_page = (PROG_SEG_MAX - 1) / prog_page_size;
	}
	else if (Val == 66) // 下一页
	{
		// 小于尾段所在页
		if (mb_reg_remote_opt_prog_page < seg_max / prog_page_size)
			mb_reg_remote_opt_prog_page++;

		// 页面范围
		if (mb_reg_remote_opt_prog_page > (PROG_SEG_MAX - 1) / prog_page_size)
			mb_reg_remote_opt_prog_page = (PROG_SEG_MAX - 1) / prog_page_size;
	}
	else if (Val == 88) // 上一页
	{
		if (mb_reg_remote_opt_prog_page)
			mb_reg_remote_opt_prog_page--;
	}
}
#endif
